package services

import (
	comm "com.wangzhumo.lottery/common"
	"com.wangzhumo.lottery/dao"
	"com.wangzhumo.lottery/datasource"
	"com.wangzhumo.lottery/models"
	"fmt"
	"github.com/gomodule/redigo/redis"
	"log"
)

type BlackIpService interface {
	Get(id int) (*models.IpBlack, error)
	GetAll(page, size int) ([]models.IpBlack, error)
	CountAll() int64
	Search(ip string) []models.IpBlack
	Update(user *models.IpBlack, columns []string) error
	Insert(user *models.IpBlack) error
	GetByIp(ip string) *models.IpBlack
}




type blackIpService struct {
	dao *dao.BlackIpDao
}


// 频繁修改
// -------------------cache---------------------
func (b *blackIpService) getIpByCache(ip string) *models.IpBlack {
	// key
	key := fmt.Sprintf("info_blackip_%s",ip)
	redisConn := datasource.InstanceRedis()

	stringMap, err := redis.StringMap(redisConn.Do("HGETALL", key))
	if err != nil {
		log.Println("blackIpService.getIpByCache redis HGETALL key = ",key," err + ",err)
		return nil
	}

	// 判断数据
	blackIpStr := comm.GetStringFromStringMap(stringMap, "Ip","")
	if blackIpStr == "" {
		return nil
	}

	// 解析数据
	blackIp := &models.IpBlack{
		Id: int(comm.GetInt64FromStringMap(stringMap, "Id", 0)),
		Ip:         blackIpStr,
		Blacktime:  int(comm.GetInt64FromStringMap(stringMap, "Blacktime", 0)),
		SysUpdated: int(comm.GetInt64FromStringMap(stringMap, "SysUpdated", 0)),
		SysCreated: int(comm.GetInt64FromStringMap(stringMap, "SysCreated", 0)),
	}
	return blackIp
}

func (b *blackIpService) saveIpCache(ip *models.IpBlack)  {
	if ip == nil || ip.Ip == "" {
		return
	}
	key := fmt.Sprintf("info_blackip_%s",ip.Ip)
	redisConn := datasource.InstanceRedis()

	params := redis.Args{key}
	if ip.Id > 0 {
		params = params.Add("Blacktime",ip.Blacktime)
		params = params.Add("SysUpdated",ip.SysUpdated)
		params = params.Add("SysCreated",ip.SysCreated)
	}
	// save
	_, err := redisConn.Do("HMSET", params)
	if err != nil {
		log.Println("blackIpService.saveIpCache redis HMSET key = ",key," err + ",err)
	}
}

func (b *blackIpService) updateIpCache(ip *models.IpBlack)  {
	if ip == nil || ip.Id <= 0 {
		return
	}
	key := fmt.Sprintf("info_blackip_%s",ip.Ip)
	redisConn := datasource.InstanceRedis()
	_, err := redisConn.Do("DEL", key)
	if err != nil {
		log.Println("blackIpService.updateIpCache redis DEL key = ",key," err + ",err)
	}
}

// -------------------cache---------------------


func (b *blackIpService) Get(id int) (*models.IpBlack, error) {
	return b.dao.Get(id)
}

func (b *blackIpService) GetAll(page, size int) ([]models.IpBlack, error) {
	return b.dao.GetAll(page, size)
}

func (b *blackIpService) CountAll() int64 {
	return b.dao.CountAll()
}

func (b *blackIpService) Search(ip string) []models.IpBlack {
	return b.dao.Search(ip)
}

func (b *blackIpService) Update(ip *models.IpBlack, columns []string) error {
	b.updateIpCache(ip)
	return b.dao.Update(ip, columns)
}

func (b *blackIpService) Insert(ip *models.IpBlack) error {
	return b.dao.Insert(ip)
}

func (b *blackIpService) GetByIp(ip string) *models.IpBlack {
	blackIp := b.getIpByCache(ip)
	if blackIp == nil || blackIp.Ip == "" {
		blackIp := b.dao.GetByIp(ip)
		if blackIp == nil || blackIp.Ip == "" {
			// 如果为空，也存入一个空的到redis,避免下次还要读数据库
			blackIp = &models.IpBlack{Ip: ip}
		}
		b.saveIpCache(blackIp)
	}
	return blackIp
}

func NewBlackIpServices() BlackIpService {
	return &blackIpService{dao: dao.NewBlackIpDao(datasource.InstanceDB())}
}
